package com.tempjob.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @author hui
 * @Date 2021/3/26 16:36
 **/
public class CommFunction {

    private static Logger logger = LoggerFactory.getLogger(CommFunction.class);

    //电话号码正则
    public static final String TEL_REGEXP = "^1[3456789][0-9]{9}$";

    /**
     * 生成指定长度的随机字符串
     *
     * @param length
     * @return
     */
    public static String getRandomString(int length) { // length表示生成字符串的长度
        String base = "abcdefhjkmnpqrstuvwxyz2345678";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = RandomUtils.nextInt(0, base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    public static String getRandomCode(int length) { // length表示生成字符串的长度
        String base = "0123456789";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = RandomUtils.nextInt(0, base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 正则匹配手机号码
     *
     * @param mobile
     * @return
     */
    public static boolean checkMobile(String mobile) {
        String regExp = "^1[3456789][0-9]{9}$";
        return Pattern.compile(regExp).matcher(mobile).matches();
    }

    /**
     * 这里实现一个简单的唯一码
     *
     * @return
     */
    public static String getRequestId() {
        int rand = RandomUtils.nextInt(0, 9999);
        String ltime = new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date()).toString() + String.valueOf(rand);
        return ltime;
    }

    /**
     * 转换参数
     *
     * @param map
     * @return
     */
    public static String getUrlParamsByMap(Map map) {
        if (map == null) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        for (Object key : map.keySet()) {
            if (key != null && !key.equals("")) {
                Object value = map.get(key);
                if (value == null) {
                    sb.append(key + "=" + map.get(key));
                } else {
                    sb.append(key + "=" + map.get(key).toString());
                }
                sb.append("&");
            }
        }
        String s = sb.toString();
        if (s.endsWith("&")) {
            s = StringUtils.substringBeforeLast(s, "&");
        }
        return s;
    }

    /**
     * 获取列表数据
     *
     * @param
     * @param cookie
     * @param targetUrl
     * @return
     */
    public static <T> List<T> getDataList(String targetUrl, Map<String, Object> params, String cookie, Class<T> clazz) {
        try {
            String listData = HttpUtils.sendBodyPost(targetUrl, CommFunction.getUrlParamsByMap(params), cookie);
//        logger.info("getDataList,target:{},req:{},res:{}", targetUrl, params, listData);
            JSONObject resData = JSON.parseObject(listData);
            Integer total = resData.getInteger("total");
            String rows = resData.getString("rows");
            if (total < 1 || StringUtils.isEmpty(rows)) {
                return null;
            }
            List<T> datas = JSON.parseArray(rows, clazz);
            if (!datas.isEmpty()) {
                return datas;
            }
        } catch (Exception e) {
            logger.error("获取表格数据错误！", e);
        }
        return null;
    }

    /**
     * 获取列表数据
     *
     * @param
     * @param cookie
     * @param targetUrl
     * @return
     */
    public static <T> List<T> getDataListWithExc(String targetUrl, Map<String, Object> params, String cookie, Class<T> clazz) {
        String listData = HttpUtils.sendBodyPost(targetUrl, CommFunction.getUrlParamsByMap(params), cookie);
//        logger.info("getDataList,target:{},req:{},res:{}", targetUrl, params, listData);
        JSONObject resData = JSON.parseObject(listData);
        Integer total = resData.getInteger("total");
        String rows = resData.getString("rows");
        if (total < 1 || StringUtils.isEmpty(rows)) {
            return null;
        }
        List<T> datas = JSON.parseArray(rows, clazz);
        if (!datas.isEmpty()) {
            return datas;
        }
        return null;
    }


    /**
     * 获取所有列表信息 --用于数据量较小的地方，一次取出所有列表数据
     *
     * @param targetUrl
     * @param pageSize
     * @param params
     * @param cookie
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> getAllDataList(String targetUrl, Integer pageSize, String cookie, HashMap<String, Object> params, Class<T> clazz) {
        List<T> list = new ArrayList<>();
        Integer page = 1;
        if (params == null) {
            params = new HashMap<>();
        }
        params.put("page", page);
        params.put("rows", pageSize);
        while (true) {
            CommFunction.sleep(2);
            String listData = "";
            try {
                listData = HttpUtils.sendBodyPost(targetUrl, CommFunction.getUrlParamsByMap(params), cookie);

//            logger.info("getDataList,target:{},req:{},res:{}", targetUrl, params, listData);
                JSONObject resData = JSON.parseObject(listData);
                Integer total = resData.getInteger("total");
                String rows = resData.getString("rows");
                if (total < 1 || StringUtils.isEmpty(rows)) {
                    return list;
                }
                List<T> datas = JSON.parseArray(rows, clazz);
                if (datas.isEmpty() || datas.size() == 0) {
                    return list;
                }
                list.addAll(datas);
                if (datas.size() <= pageSize) {
                    return list;
                }
                page++;
                params.put("page", page);
            } catch (Exception e) {
                logger.error("请求列表数据：{},{},出错！", targetUrl, params, e);
                break;
            }
        }
        return list;
    }

    /**
     * 随机休眠
     *
     * @param randomMax
     */
    public static void sleep(Integer randomMax) {
        try {
            Random r = new Random(1);
            int sleepTime = r.nextInt(randomMax * 10);
            Thread.sleep(sleepTime * 100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
//
//    /**
//     * 获取办理人员办理状态
//     * @param sendState
//     * @param backState
//     * @return
//     */
//    public static Integer getWfStatus(Integer sendState,Integer backState){
//        if(sendState.equals(22) && backState.equals(0)){
//            return 1;//待分派
//        } else if(sendState.equals(23) && backState.equals(0)){
//            return 2;//下级办理中
//        }else if(sendState.equals(23) && (backState.equals(11)|| backState.equals(21))){
//            return 3;//下级已办闭待审核回复
//        }else if((sendState.equals(40)) && backState.equals(11)){
//            return 4;//下级退回
//        }else if((sendState.equals(40)) && backState.equals(21)){
//            return 5;//退回效能办
//        }else if((sendState.equals(40))){
//            return 6;//上级不同意退回
//        }else if((sendState.equals(40))){
//            return 7;//待本部门回复
//        }else if((sendState.equals(40))){
//            return 8;//待本部门审核
//        }else if((sendState.equals(40))){
//            return 9;//工单已回已审
//        }
//        return 0;//未处理
//    }


    public static String getRealIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    public static String generateSign(Map<String, Object> params) {
        params.put("account","");
        params.put("password","");
        params.put("timestamp",(new Date()).getTime());
        // 1. 创建一个新的Map，用于存放排序后的参数
        Map<String, Object> sortedParams = new TreeMap<>(params);

        // 2. 移除原有的sign参数，如果存在
        sortedParams.remove("sign");

        // 4. 将排序后的参数转换为字符串格式
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> entry : sortedParams.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        // 去掉末尾的 &
        if (sb.length() > 0) {
            sb.setLength(sb.length() - 1);
        }

        // 5. 使用MD5算法进行加密
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashBytes = md.digest(sb.toString().getBytes(StandardCharsets.UTF_8));
            // 6. 转换为32位小写十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                hexString.append(String.format("%02x", b & 0xff));
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 algorithm not found", e);
        }
    }

    public static Integer getwfStatus(Integer sendState,Integer backState){
//        @ApiModelProperty("状态:0已退单1办理中2已办毕")
        if (sendState.equals(40)) {
            return 0;
        }
        if(backState.equals(11) || backState.equals(21)){
            return 2;
        }
        return 1;
    }


    public static String md5(String input) {
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        byte[] messageDigest = md.digest(input.getBytes());
        StringBuilder hexString = new StringBuilder();
        for (byte b : messageDigest) {
            String hex = Integer.toHexString(0xFF & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

}
